package com.example.test001;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 调用事件发布者
 */
@RestController
//@RequiredArgsConstructor
@Api(tags={"test"})
public class UserController {
    @Resource(name = "customThreadPool")
    private ThreadPoolTaskExecutor customThreadPool;


    @Resource(name = "stockTaskExecutor")
    private ThreadPoolTaskExecutor stockTaskExecutor;

    @Resource(name = "stockTaskExecutor1")
    private ThreadPoolTaskExecutor stockTaskExecutor1;

    private static final ThreadLocal<User> threadLocalConnection = new ThreadLocal<>();



    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况
     * 一次请求4次，四个线程走的是核心线程数
     * @return
     */
    @RequestMapping(value = "/testThreadCore01" )
    @ApiOperation("testThreadCore01")
    public User testThreadCore01(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }


    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况
     * 一次请求9次，发现剩余的四个线程走的是核心线程数
     * @return
     */
    @RequestMapping(value = "/testThreadCore" )
    @ApiOperation("testThreadCore")
    public User testThreadCore(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 9; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }

    @RequestMapping(value = "/testThreadCore001" )
    @ApiOperation("testThreadCore001")
    public User testThreadCore001(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 19; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }



    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况
     * 一次请求23次，发现走的是核心线程数
     * @return
     */
    @RequestMapping(value = "/testThreadCore11" )
    @ApiOperation("testThreadCore11")
    public User testThreadCore11(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 25; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }


    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况，默认拒绝策略
     * 一次请求29次，发现走核心线程和普通线程
     * @return
     */
    @RequestMapping(value = "/testThreadCore1" )
    @ApiOperation("testThreadCore1")
    public User testThreadCore1(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 29; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }

    public  boolean isCoreThread(Thread thread, int corePoolSize) {
        // 核心线程的优先级通常是Thread.NORM_PRIORITY
        boolean isCore = thread.getPriority() == Thread.NORM_PRIORITY && thread.isDaemon();
        // 如果有多个线程，检查是否还有非核心线程
        if (isCore && customThreadPool.getPoolSize() > corePoolSize) {
            // 如果当前线程数超过核心线程数，则不是核心线程
            isCore = false;
        }
        return isCore;
    }

    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况，默认拒绝策略
     * 一次请求34次，发现走核心线程和普通线程，重复测试几次发现会报错，因为是用的默认拒绝策略
     * @return
     */
    @RequestMapping(value = "/testThreadCore2" )
    @ApiOperation("testThreadCore2")
    public User testThreadCore2(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 34; i++) {
                futures.add(customThreadPool.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }

    /**
     * 测试线程池在设置核心线程数只有5，最大线程数是10，队列25的情况，设置拒绝策略是CallerRunsPolicy()
     * 一次请求40次，重复测试几次发现不会报错，因为拒绝策略是CallerRunsPolicy()
     * @return
     */
    @RequestMapping(value = "/testThreadCore3" )
    @ApiOperation("testThreadCore3")
    public User testThreadCore3(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 40; i++) {
                futures.add(stockTaskExecutor.submit(() -> useThreadLocalWithPool1()));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }

    @RequestMapping(value = "/testThreadCore4" )
    @ApiOperation("testThreadCore4")
    public User testThreadCore4(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 40; i++) {
                futures.add(stockTaskExecutor.submit(new MyTask(i)));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }


    @RequestMapping(value = "/testThreadCore5" )
    @ApiOperation("testThreadCore5")
    public User testThreadCore5(){
        try {
            List<Future<?>> futures = new ArrayList<>();
            for (int i = 0; i < 40; i++) {
                futures.add(stockTaskExecutor1.submit(new MyTask(i)));
            }
            // 等待所有任务完成
            for (Future<?> future : futures) {
                future.get();
            }
            System.out.println("所有任务已完成");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
//            customThreadPool.shutdown(); // 关闭线程池
        }
        return null;
    }



    public void useThreadLocalWithPool() {
        // 使用ThreadLocal
//        customThreadPool.submit(() -> {
            User connection = getConnection();
            try {
                // 执行数据库操作
            } finally {
                // 清理ThreadLocal资源
                closeConnection();
            }
//        });


    }

    public void useThreadLocalWithPool1()  {
        // 使用ThreadLocal
//        customThreadPool.submit(() -> {
            try {
                Thread.sleep(1000L);
                String name = Thread.currentThread().getName();
                long threadId = Thread.currentThread().getId();
                System.out.printf("%s -%s- Thread ID: %d%n", name, System.currentTimeMillis(),threadId);

//                if ((Integer)customThreadPool.getClass().getMethod("getActiveCount").invoke(customThreadPool) <= (Integer)customThreadPool.getClass().getMethod("getCorePoolSize").invoke(customThreadPool)) {
//                    System.out.printf("%s -%s - Thread ID: %d%n",true, name, threadId);
//                } else {
//                    System.out.printf("%s -%s - Thread ID: %d%n",false, name, threadId);
//                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }


//        });


    }
//    public void useThreadLocalWithPool2() {
//        // 使用ThreadLocal
//        stockTaskExecutor.submit(() -> {
//            String name = Thread.currentThread().getName();
//            long threadId = Thread.currentThread().getId();
//            System.out.printf("%s - Thread ID: %d%n", name, threadId);
//        });
//
//
//    }

    public  User getConnection() {
        User user = threadLocalConnection.get();
        if (user == null) {
            String name = Thread.currentThread().getName();
            System.out.println(name);
            user = new User();
            threadLocalConnection.set(user);
        }
        return user;
    }

    public static void closeConnection() {
        User connection = threadLocalConnection.get();
        if (connection != null) {
            try {
                System.out.println("1111");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                threadLocalConnection.remove();
            }
        }
    }

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 创建线程池
        ExecutorService executor = new ThreadPoolExecutor(
                5,
                10,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(25));
        // 提交任务到线程池
        for (int i = 0; i < 34; i++) {
            final int finalI = i;
            Runnable worker = () -> {
                try {
                    long millis=0L;
//                     millis = (long) (Math.random() * 1000);
//                    if(2 > finalI){
//                        Thread.sleep(millis);
//                    }

                    if ((Integer)executor.getClass().getMethod("getActiveCount").invoke(executor) <= (Integer)executor.getClass().getMethod("getCorePoolSize").invoke(executor)) {
                        System.out.println(finalI+" is core-"+millis);
                    } else {
                        System.out.println(finalI+" non-core-"+millis);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            executor.execute(worker);
        }
        executor.shutdown();
    }

}
